﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLite.Collections;

using Castle.Core.Interceptor;
using Castle.DynamicProxy;
using NLite.Mini.Proxy;

namespace NLite.Interceptor.Mini
{
    public class ProxyFactory : IProxyFactory
    {

        private Castle.DynamicProxy.ProxyGenerator generator;

        public ProxyFactory()
        {
            generator = new ProxyGenerator();
        }

        public object Create(NLite.Mini.Context.IPreCreationContext ctx, object instance, params object[] constructorArguments)
        {
            var targetInterceptors = new Castle.Core.Interceptor.IInterceptor[] { new InterceptorAdapter(new InterceptorBroker()) };

            if (instance != null)
            {
                var interfaces = ctx.Component.Contracts.Where(i => i.IsInterface).ToList();
                var first = interfaces[0];
                interfaces.Remove(first);

                return generator.CreateInterfaceProxyWithTarget(first, interfaces.ToArray(), instance, targetInterceptors);
            }

            return generator.CreateClassProxy(ctx.Component.Implementation, targetInterceptors, constructorArguments);
        }



        public bool RequiresTargetInstance(NLite.IKernel kernel, IComponentInfo model)
        {
            if (model.Implementation.IsValueType
                || model.Implementation.IsSealed)
                return true;
            return false;
        }

        public bool ShouldCreateProxy(IComponentInfo model)
        {
            return model.ExtendedProperties.Contains("proxy");
        }
    }
}
